﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;


namespace UssdService
{
    /// <summary>
    /// Summary description for UssdService
    /// </summary>
    [WebService(Namespace = "http://api.hello.com.kh/UssdService")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class UssdService : System.Web.Services.WebService
    {
        private salesystem.PrepaidServiceService wsPrepaidService = new salesystem.PrepaidServiceService();
        private string main_menu = "Main Menu\n1. Stock Transfer\n2. Daily Report\n3. Period Report\n4. Change PIN";
        private string prompt_pin = "input PIN:";
        private string prompt_invalid = " Invalid menu option!\nPress 0 to main menu";
        private string prompt_dealercode = "Input dealer code:\n\nPress 0 to main menu";
        private string prompt_startdate = "Input start date(ddmmyy):\n\nPress 0 to main menu";
        private string prompt_enddate = "Input end date(ddmmyy):\n\n0. back to main menu";
        private string prompt_confirm_report = "Period Report:\nFrom {0}\nTo {1}\nConfirm?\n\nPress 1 to confirm\nPress 0 to main menu";
        private string prompt_confirm_SN = "Transfer:\nFrom {0}\nTo {1}\nConfirm?\n\nPress 1 to confirm\nPress 0 to main menu";
        private string prompt_newpin = "Input new PIN:\nPress 0 to main menu";
        private string prompt_cardtype = "1. SIM card\n 2.Hello Card\n\nPress 0 to main menu";
        private string prompt_confirm_newpin = "Confirm new PIN:\nPress 0 to main menu";
        private string prompt_startSN = "Input Start SN:\nPress 0 to main menu";
        private string prompt_EndSN = "Input End SN:\nPress 0 to main menu";
        public UssdService()
        {
          

        }
        private bool  VerifyDate(string Date) {

            return true;
        }
        private bool ValidatePin(string iMsisdn, string iPincode) {
            bool respcode = false;
            try
            {
                respcode = wsPrepaidService.check_mpin( iMsisdn, iPincode);
            }
            catch (Exception ex) { 
                // log error
                //
            
            }
            return respcode;
        }
        private bool ReqDailyReport(string iMsisdn, string iPincode,string commandid,string dealercode,string itemcode,string startsn,string endsn,string startdate,string enddate,string newpin) {
            bool respcode = false;
            try
            {
                wsPrepaidService.stock_tranfer(iMsisdn, iPincode, commandid, dealercode,itemcode,startsn,endsn, startdate, enddate, newpin);
                respcode = true;
            }
            catch (Exception ex)
            {
                // log error

            }
            return respcode;
        }
        [WebMethod]
        public UssdResponse UssdRequest(string imsisdn, string ussdstring, string userdata, int state, SaleData SaleObject) {
            
            UssdResponse resp = new UssdResponse();
            resp.SaleObject = SaleObject;
            switch (state)
            {
                case 0:

                    if (ussdstring == "*2222#")
                    {
                        #region Menu
                        resp.Notify = false;
                        resp.UssdString = prompt_pin;
                        resp.State = 99;
                        #endregion
                    }else if (ussdstring.StartsWith("*2222*")){
                        resp.UssdString = "Invalid Request, please dial *2222#";
                    }else
                    {

                        resp.UssdString = "Your number is " + imsisdn + ", thanks for using hello";
                    }
                    break;
                case 99:
                    if (ValidatePin(imsisdn, ussdstring.Trim()))
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                       
                        resp.SaleObject.PinCode = ussdstring.Trim();
                       
                    }
                    else
                    {

                        resp.UssdString ="Invalid PIN,Please try again.\n" + prompt_pin;
                        resp.State = 99;

                    }
                    resp.Notify = false;
                    break;


                case 1:
                    switch (ussdstring)
                    {
                        case "1":
                            // stock transfer
                            resp.UssdString = prompt_dealercode;
                            resp.State = 11;
                            resp.Notify = false;
                            break;
                        case "2":
                            // daily report
                            if (ReqDailyReport(imsisdn, resp.SaleObject.PinCode,"2","","","","","","",""))
                            {

                                resp.UssdString = "Your requested operation is accepted.\nPress 0 to main menu";
                            }
                            else
                            {
                                resp.UssdString = "Service is not available ,Please try again later.\nPress 0 to main menu";
                            }

                            resp.State = 19;
                            resp.Notify = false;
                            break;
                        case "3":
                            // period report
                            resp.UssdString = prompt_startdate;
                            resp.State = 13;
                            resp.Notify = false;
                            break;
                        case "4":
                            // change Pin
                            resp.UssdString = prompt_newpin;
                            resp.State = 14;
                            resp.Notify = false;
                            break;

                        default:
                            resp.UssdString = prompt_invalid;
                            resp.State = 19;
                            resp.Notify = false;
                            // default implement
                            break;
                    }
                    break;
                case 11:
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {
                        resp.SaleObject.DealerCode = ussdstring;
                        resp.UssdString = prompt_cardtype;
                        resp.State = 111;
                        resp.Notify = false;
                    }
                    break;
                case 111:
                    if (ussdstring == "1" || ussdstring == "2")
                    {
                        resp.SaleObject.ItemCode = ussdstring;
                        resp.UssdString = prompt_startSN;
                        resp.State = 112;
                        resp.Notify = false;


                    }
                    else if (ussdstring == "0") {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {
                        resp.UssdString = prompt_cardtype;
                        resp.State = 111;
                        resp.Notify = false;
                    }
                    break;
                case 112:
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else{
                        resp.SaleObject.FromSerial = ussdstring;
                        resp.UssdString = prompt_EndSN;
                        resp.State = 113;
                        resp.Notify = false;
                    }
                    break;
                case 113:
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {

                        resp.SaleObject.ToSerial = ussdstring;
                        resp.UssdString = string.Format(prompt_confirm_SN, resp.SaleObject.FromSerial, resp.SaleObject.ToSerial);


                        resp.State = 114;
                        resp.Notify = false;
                    }
                    break;
                case 114:
                    if (ussdstring == "1")
                    {
                        //
                        if (ReqDailyReport(imsisdn, resp.SaleObject.PinCode, "1", resp.SaleObject.DealerCode, resp.SaleObject.ItemCode, resp.SaleObject.FromSerial, resp.SaleObject.ToSerial, "","", ""))
                        {

                            resp.UssdString = "Your requested operation is accepted.\nPress 0 to main menu";
                        }
                        else
                        {
                            resp.UssdString = "Service is not available ,Please try again later.\nPress 0 to main menu";
                        }

                        resp.State = 19;
                        resp.Notify = false;

                    }
                    else if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {
                        resp.UssdString = string.Format(prompt_confirm_SN, resp.SaleObject.FromSerial, resp.SaleObject.ToSerial);
                        resp.State = 114;
                        resp.Notify = false;



                    }
                    break;
                case 13:
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {

                        resp.SaleObject.StartDate = ussdstring;
                        resp.UssdString = prompt_enddate;
                        resp.State = 131;
                        resp.Notify = false;
                    }
                    break;
                case 131:
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {

                        resp.SaleObject.EndDate = ussdstring;
                        resp.UssdString = string.Format(prompt_confirm_report, resp.SaleObject.StartDate, resp.SaleObject.EndDate); ;
                        resp.State = 132;
                        resp.Notify = false;
                    }
                    break;
                case 132:
                    //
                    if (ussdstring == "1")
                    {
                        //
                        if (ReqDailyReport(imsisdn, resp.SaleObject.PinCode, "3", "", "", "", "", "",resp.SaleObject.StartDate, resp.SaleObject.EndDate))
                        {

                            resp.UssdString = "Your requested operation is accepted.\nPress 0 to main menu";
                        }
                        else
                        {
                            resp.UssdString = "Service is not available ,Please try again later.\nPress 0 to main menu";
                        }

                        resp.State = 19;
                        resp.Notify = false;

                    }
                    else if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {
                        resp.UssdString = string.Format(prompt_confirm_report, resp.SaleObject.StartDate, resp.SaleObject.EndDate);
                        resp.State = 132;
                        resp.Notify = false;



                    }
                    break;
                    
                case 19:
                    // invalid menu
                    if (ussdstring == "0")
                    {
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {
                        resp.UssdString = prompt_invalid;
                        resp.State = 19;
                        resp.Notify = false;

                    }
                    break;
                case 14:
                    //1- Verify PIN rule?
                    //2- Store New PIN
                    //2- Ask confirm PIN
                    //
                    if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    else
                    {

                        resp.UssdString = prompt_confirm_newpin;
                        resp.Notify = false;
                        resp.State = 141;
                        resp.SaleObject.NewPIN = ussdstring.Trim();
                    }
                    break;

                case 141:
                    // check if confirm pin/new pin
                    if (ussdstring == resp.SaleObject.NewPIN)
                    {
                        // pin is match?
                        // Todo Send Request 
                        if (ReqDailyReport(imsisdn, resp.SaleObject.PinCode, "4", "", "", "", "", "","", resp.SaleObject.NewPIN))
                        {

                            resp.UssdString = "Your requested operation is accepted.\nPress 0 to main menu";
                        }
                        else
                        {
                            resp.UssdString = "Service is not available ,Please try again later.\nPress 0 to main menu";
                        }

                        resp.Notify = false;
                        resp.State = 19;
                    }else if (ussdstring == "0")
                    {
                        // show menu?
                        resp.UssdString = main_menu;
                        resp.State = 1;
                        resp.Notify = false;
                    }
                    
                    else
                    {
                        // pin is not match
                        resp.UssdString = "PIN Missed match!\n" + prompt_confirm_newpin;
                        resp.State = 141;
                        resp.Notify = false;
                    }
                    break;

                default:
                    resp.Notify = true;

                    resp.UssdString = "No impliment";
                    break;

            }
            return resp;
        }
       
        public class UssdResponse {


            public string UssdString;
            public int State;
            public bool Notify;
            public string UserData;
            public SaleData SaleObject;
            public UssdResponse() {
                UssdString = "Service is not available";
                State = 0;
                Notify = true;
                UserData = "";
            }
            public UssdResponse(string iUssdString,string iUserData,int iState,bool iNotify=true)
            {
                UssdString = iUssdString;
                State = iState;
                Notify = iNotify;
                UserData = iUserData;
            }
        }
        public class SaleData
        {


            public string PinCode;
            public string StartDate;
            public string EndDate;
            public string DealerCode;
            public string ItemCode;
            public string ToSerial;
            public string FromSerial;
            public string NewPIN;

            public SaleData()
            {
                
            }
            
        }
 
    }
}